----------------------------------------------------------------------------------------------------------------------------------
--[[

    天赋树

    self.talents = {
        ["points"] = 0, -- 当前点数 .占位符号。
        ["talent_name"] = true,
    }

    服务端监听事件 hutao_com_talent_tree_updated 来 刷新功能开启、关闭。
    客户端监听 hutao_event.talent_tree_client_side_updated 来刷新功能开启、关闭。
    
]]--
----------------------------------------------------------------------------------------------------------------------------------
local hutao_com_talent_tree = Class(function(self, inst)
    self.inst = inst

    self.DataTable = {}
    self.TempTable = {}
    self._onload_fns = {}
    self._onsave_fns = {}

    --------------------------------------------------------------------------
    --- 天赋数据
        self.talents = {
            ["points"] = 0, -- 当前点数 .占位符号。
        }
        self:AddOnSaveFn(function()
            self:Set("talents", self.talents)
        end)
        self:AddOnLoadFn(function()
            self.talents = self:Get("talents") or self.talents
            self:Talent_Tree_Sync_2_Client()
        end)
    --------------------------------------------------------------------------
    --- 客户端来的解锁命令
        inst:ListenForEvent("hutao_event.talent_tree_unlock_cmd_from_client",function(inst,cmd)
            cmd = cmd or {}
            if cmd.unlock_talent then
                self:Unlock(cmd.unlock_talent)
            end
            if cmd.reset then
                self:Reset()
            end
        end)
    --------------------------------------------------------------------------
    --- time out
        self.__sync_time_out_task = nil
        self.sync_time_out = 2
        inst:ListenForEvent("hutao_event.talent_tree_data_updated_from_server",function()
            if self.__sync_time_out_task then
                self.__sync_time_out_task:Cancel()
                self.__sync_time_out_task = nil
            end
        end)
    --------------------------------------------------------------------------
    --- 最大点数
        self.max_got_points = 5
        self.reset_punishment = 0
    --------------------------------------------------------------------------
end,
nil,
{

})
------------------------------------------------------------------------------------------------------------------------------
--- RPC
    function hutao_com_talent_tree:GetRPC()
        return self.inst.components.hutao_com_rpc_event
    end
    function hutao_com_talent_tree:Talent_Tree_Sync_2_Client()
        if self.__temp_sync_task then
            self.__temp_sync_task:Cancel()
            self.__temp_sync_task = nil
        end
        self.__temp_sync_task = self.inst:DoTaskInTime(0,function()
            self:GetRPC():PushEvent("hutao_event.talent_tree_data_from_server",self.talents)
            self.inst:PushEvent("hutao_com_talent_tree_updated")
            if self.__sync_time_out_task then
                self.__sync_time_out_task:Cancel()
                self.__sync_time_out_task = nil
            end
            self.__sync_time_out_task = self.inst:DoTaskInTime(self.sync_time_out,function()
                self.__sync_time_out_task = nil
                self:Talent_Tree_Sync_2_Client()
            end)
        end)
    end
------------------------------------------------------------------------------------------------------------------------------
--- 天赋点数
    function hutao_com_talent_tree:GetPoints()
        local points = self.talents["points"] or 0
        return points
    end
    function hutao_com_talent_tree:SetPoints(points)
        self.talents["points"] = points
        self:Talent_Tree_Sync_2_Client()
    end
    function hutao_com_talent_tree:AddPoint(num)
        local points = math.max(0,self:GetPoints() + num)
        self:SetPoints(points)
    end
------------------------------------------------------------------------------------------------------------------------------
--- 最大点数
    function hutao_com_talent_tree:SetMaxCanGotPoints(max_got_points)
        self.max_got_points = max_got_points
    end
    function hutao_com_talent_tree:AddPointsByMaxCheck(num)
        if num <= 0 then
            return
        end
        local got_points = self:Get("got_points",0)
        if got_points + num > self.max_got_points then
            num = self.max_got_points - got_points
            if num > 0 then
                self:AddPoint(num)
                self:Add("got_points",num)
                self.inst:PushEvent("hutao_com_talent_tree.got_new_points")
            end
        else
            self:AddPoint(num)
            self:Add("got_points",num)
            self.inst:PushEvent("hutao_com_talent_tree.got_new_points")
        end
    end
------------------------------------------------------------------------------------------------------------------------------
--- 回收
    function hutao_com_talent_tree:SetResetPunishmentNum(reset_punishment)
        self.reset_punishment = math.abs(reset_punishment)
    end
    function hutao_com_talent_tree:Reset()
        local actived_num = 0
        for temp, v in pairs(self.talents) do
            if temp ~= "points" and self.talents[temp] == true  then
                actived_num = actived_num + 1
                self.talents[temp] = false
            end
        end
        self:AddPoint(actived_num)
        --------------------------------------------------------------------------
            --- 惩罚：洗一次扣一点。
            if self:GetPoints() > 0 then
                -- self:AddPoint(-1)
                self:AddPoint(-1*math.abs(self.reset_punishment))
                self:Add("got_points",-1,0,9999)
            end
        --------------------------------------------------------------------------
        self:Talent_Tree_Sync_2_Client()
        self.inst:PushEvent("hutao_com_talent_tree_reset")
    end
------------------------------------------------------------------------------------------------------------------------------
---
    function hutao_com_talent_tree:IsUnlocked(index)
        if index ~= "points" then
            return self.talents[index] == true
        end
    end
    function hutao_com_talent_tree:ForceUnlock(index)
        if index ~= "points" then
            self.talents[index] = true
            self.inst:PushEvent("hutao_com_talent_tree_unlock",index)
        end
        self:Talent_Tree_Sync_2_Client()
    end
    function hutao_com_talent_tree:Unlock(index)
        if index == "points" then
            return
        end
        if self:GetPoints() > 0 and not self:IsUnlocked(index) then
            self:AddPoint(-1)
            self:ForceUnlock(index)
        else
            self:Talent_Tree_Sync_2_Client()    
        end
    end
------------------------------------------------------------------------------------------------------------------------------
---
    function hutao_com_talent_tree:Print()
        print("+++++++++ hutao_com_talent_tree +++++++++++++")
        for k, v in pairs(self.talents) do
            print(k,v)
        end
        print("+++++++++++++++++++++++++++++++++++++++++++++++")
    end
------------------------------------------------------------------------------------------------------------------------------
----- onload/onsave 函数
    function hutao_com_talent_tree:AddOnLoadFn(fn)
        if type(fn) == "function" then
            table.insert(self._onload_fns, fn)
        end
    end
    function hutao_com_talent_tree:ActiveOnLoadFns()
        for k, temp_fn in pairs(self._onload_fns) do
            temp_fn(self)
        end
    end
    function hutao_com_talent_tree:AddOnSaveFn(fn)
        if type(fn) == "function" then
            table.insert(self._onsave_fns, fn)
        end
    end
    function hutao_com_talent_tree:ActiveOnSaveFns()
        for k, temp_fn in pairs(self._onsave_fns) do
            temp_fn(self)
        end
    end
------------------------------------------------------------------------------------------------------------------------------
----- 数据读取/储存
    function hutao_com_talent_tree:Get(index,default)
        if index then
            return self.DataTable[index] or default
        end
        return nil or default
    end
    function hutao_com_talent_tree:Set(index,theData)
        if index then
            self.DataTable[index] = theData
        end
    end

    function hutao_com_talent_tree:Add(index,num,min,max)
        if index then
            if min and max then
                local ret = (self.DataTable[index] or 0) + ( num or 0 )
                ret = math.clamp(ret,min,max)
                self.DataTable[index] = ret
                return ret
            else
                self.DataTable[index] = (self.DataTable[index] or 0) + ( num or 0 )
                return self.DataTable[index]
            end
        end
        return 0
    end
------------------------------------------------------------------------------------------------------------------------------

------------------------------------------------------------------------------------------------------------------------------
    function hutao_com_talent_tree:OnSave()
        self:ActiveOnSaveFns()
        local data =
        {
            DataTable = self.DataTable
        }
        return next(data) ~= nil and data or nil
    end

    function hutao_com_talent_tree:OnLoad(data)
        if data.DataTable then
            self.DataTable = data.DataTable
        end
        self:ActiveOnLoadFns()
    end
------------------------------------------------------------------------------------------------------------------------------
return hutao_com_talent_tree







